
package com.twb.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.twb.core.base.entity.BaseLoginUser;
import com.twb.core.base.entity.TwbPageInfo;
import com.twb.core.base.service.impl.BaseService;
import com.twb.core.cache.redis.RedisUtil;
import com.twb.core.exception.ServiceException;
import com.twb.core.util.BeanUtils;
import com.twb.core.util.ExcelUtils;
import com.twb.core.util.TwbPageUtil;
import com.twb.system.common.TenantConfigTypeEnums;
import com.twb.system.entity.twbTenantConfig.TwbTenantConfig;
import com.twb.system.entity.twbTenantConfig.dto.SearchTenantConfigDto;
import com.twb.system.entity.twbTenantConfig.dto.TenantConfigWxCpAppDto;
import com.twb.system.entity.twbTenantConfig.dto.TenantConfigWxCpDto;
import com.twb.system.entity.twbTenantConfig.vo.SaveTenantConfigVo;
import com.twb.system.entity.twbTenantConfig.vo.SearchTenantConfigVo;
import com.twb.system.entity.twbTenantConfig.vo.UpdateTenantConfigByIdVo;
import com.twb.system.mapper.TwbTenantConfigMapper;
import com.twb.system.service.ITwbTenantConfigService;
import com.twb.system.util.ExcelDataDicHandlerImpl;

/**
 * @author DSY
 * @ClassName: TwbTenantConfigService
 * @Description: 租户配置管理Service
 * @date 2022-12-30 16:00:28
 */
@Service("twbTenantConfigService")
public class TwbTenantConfigService extends BaseService<TwbTenantConfigMapper, TwbTenantConfig> implements ITwbTenantConfigService {

    @Autowired
    TwbTenantConfigMapper tenantConfigMapper;
    @Autowired
	private RedisUtil redisUtil;
	
	/**
	 * @Title getTenantConfig
	 * @Description 设置缓存前缀
	 * @return
	 * @author DSY
	 * @date 2021年12月25日 下午4:58:56
	 */
	public String getTenantConfig() {
		String cachePrefix = this.twbConfigProperties.getCachePrefix();
		return cachePrefix+":tenantconfig";
	}
	
	@Override
	public boolean initRedisTenantConfig(String tenantId) {
		boolean bl = false;
		Map<String, String> map = new HashMap<String, String>();
		TwbTenantConfig record = new TwbTenantConfig();
		record.setIsdel(0);
		List<TwbTenantConfig> queryForList = this.list(record);
		for (TwbTenantConfig config : queryForList) {
			map.put(config.getConfigType(), config.getConfigJson());
		}
		redisUtil.set(getTenantConfig()+":"+tenantId, map);

		bl = true;
		return bl;
	}

	@Override
	public JSONObject getRedisTenantConfigJson(String tenantId,String type) {
		Map<String, String> map = redisUtil.get(getTenantConfig()+":"+tenantId);
		if (null == map || map.isEmpty()) {
			boolean init = initRedisTenantConfig(tenantId);
			if (init) {
				map = redisUtil.get(getTenantConfig());
				if(map.isEmpty()) {
					String json = map.get(type);
					if(StringUtils.isNotBlank(json)) {
						return JSON.parseObject(json);
					}
				}
			}
		}
		return null;
	}
	
    

    @Override
    public TwbPageInfo<SearchTenantConfigDto> searchTenantConfig(SearchTenantConfigVo vo) {
        TwbPageUtil.startPage(vo);
        List<SearchTenantConfigDto> list = tenantConfigMapper.searchTenantConfig(vo);
        return TwbPageUtil.of(list);
    }

    @Override
    public SearchTenantConfigDto searchTenantConfigSum(SearchTenantConfigVo vo) {
        SearchTenantConfigDto result = tenantConfigMapper.searchTenantConfigSum(vo);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTenantConfig(SaveTenantConfigVo vo) {
        TwbTenantConfig checkVo = new TwbTenantConfig();
        // 此处需要修改为需要校验重复的字段
        checkVo.setUnionId(vo.getUnionId());
        checkVo.setIsdel(0);
        long count = this.count(checkVo);
        if (count > 0) {
            throw new ServiceException(String.format("[%s]已存在", checkVo.getUnionId()));
        }

        TwbTenantConfig record = new TwbTenantConfig();
        BeanUtils.copyProperties(vo, record);
        record.setId(this.getUUID());
        this.setCreateInfo(record);
        this.setUpdateInfo(record);
        boolean result = this.save(record);
        if(result) {
        	BaseLoginUser loginUser = this.getLoginUser();
        	initRedisTenantConfig(loginUser.getTenantId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTenantConfigById(UpdateTenantConfigByIdVo vo) {
        TwbTenantConfig record = tenantConfigMapper.selectById(vo.getId());
        if (null == record) {
            throw new ServiceException("数据不存在");
        }

        if (!vo.getUnionId().equalsIgnoreCase(record.getUnionId())) {
            TwbTenantConfig checkVo = new TwbTenantConfig();
            // 此处需要修改为需要校验重复的字段
            checkVo.setUnionId(vo.getUnionId());
            checkVo.setIsdel(0);
            long count = this.count(checkVo);
            if (count > 0) {
                throw new ServiceException(String.format("[%s]已存在", checkVo.getUnionId()));
            }
        }

        BeanUtils.copyProperties(vo, record);
        this.setUpdateInfo(record);
        boolean result = this.updateById(record);
        if(result) {
        	BaseLoginUser loginUser = this.getLoginUser();
        	initRedisTenantConfig(loginUser.getTenantId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTenantConfigByIds(String ids) {
    	boolean result = this.removeByIds(Arrays.asList(ids.split(",")));
    	if(result) {
        	BaseLoginUser loginUser = this.getLoginUser();
        	initRedisTenantConfig(loginUser.getTenantId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int logicBatchDeleteTenantConfigByIds(String ids) {
        List<String> list = new ArrayList<String>();
        Collections.addAll(list, ids.split(","));
        int result = tenantConfigMapper.logicBatchDeleteTenantConfigByIds(list);
        if(result>0) {
        	BaseLoginUser loginUser = this.getLoginUser();
        	initRedisTenantConfig(loginUser.getTenantId());
        }
        return result;
    }

    @Override
    public void exportExcel(SearchTenantConfigVo vo, HttpServletResponse response) throws Exception {
        String fileName = vo.getFileName();
        if (StringUtils.isBlank(fileName)) {
            fileName = "租户配置管理";
        }
        TwbPageInfo<SearchTenantConfigDto> pageInfo = this.searchTenantConfig(vo);
        List<SearchTenantConfigDto> list = pageInfo.getList();
        ExcelDataDicHandlerImpl excelDataDicHandlerImpl = new ExcelDataDicHandlerImpl();
        ExcelUtils.exportExcel(fileName, list, SearchTenantConfigDto.class, response, excelDataDicHandlerImpl);
    }

    @Override
    public String getWxCpAgentid(String domain) {
        SearchTenantConfigVo vo = new SearchTenantConfigVo();
        vo.setConfigType(TenantConfigTypeEnums.WX_CP.code());
        vo.setConfigJson(domain);
        List<SearchTenantConfigDto> list = tenantConfigMapper.searchTenantConfig(vo);

        List<String> agentidList = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(list)) {
            if (list.size() > 1) {
                throw new ServiceException(String.format("域名【%s】查询到多条配置", domain));
            }

            SearchTenantConfigDto configDto = list.get(0);
            TenantConfigWxCpDto wxCpDto = JSON.parseObject(configDto.getConfigJson(), TenantConfigWxCpDto.class);
            if (CollectionUtils.isNotEmpty(wxCpDto.getAppConfigs())) {
                for (TenantConfigWxCpAppDto wxCpAppDto : wxCpDto.getAppConfigs()) {
                    if (domain.equals(wxCpAppDto.getDomain()) && !agentidList.contains(wxCpAppDto.getAgentId())) {
                        agentidList.add(wxCpAppDto.getAgentId());
                    }
                }
            }

        }

        if (agentidList.size() < 1) {
            throw new ServiceException(String.format("域名【%s】未查询到配置", domain));
        }

        if (agentidList.size() > 1) {
            throw new ServiceException(String.format("域名【%s】查询到%s条配置", domain, agentidList.size()));
        }

        return agentidList.get(0);
    }

    @Override
    public TenantConfigWxCpDto getWxCpConfig(String domain) {
        SearchTenantConfigVo vo = new SearchTenantConfigVo();
        vo.setConfigType(TenantConfigTypeEnums.WX_CP.code());
        vo.setConfigJson(domain);
        List<SearchTenantConfigDto> list = tenantConfigMapper.searchTenantConfig(vo);

        List<TenantConfigWxCpAppDto> appConfigs = new ArrayList<TenantConfigWxCpAppDto>();

        TenantConfigWxCpDto wxCpDto = new TenantConfigWxCpDto();

        if (CollectionUtils.isNotEmpty(list)) {
            if (list.size() > 1) {
                throw new ServiceException(String.format("域名【%s】查询到多条配置", domain));
            }

            SearchTenantConfigDto configDto = list.get(0);
            wxCpDto = JSON.parseObject(configDto.getConfigJson(), TenantConfigWxCpDto.class);
            if (CollectionUtils.isNotEmpty(wxCpDto.getAppConfigs())) {
                for (TenantConfigWxCpAppDto wxCpAppDto : wxCpDto.getAppConfigs()) {
                    if (domain.equals(wxCpAppDto.getDomain()) && !appConfigs.contains(wxCpAppDto)) {
                        appConfigs.add(wxCpAppDto);
                    }
                }
            }
        }

        if (appConfigs.size() < 1) {
            throw new ServiceException(String.format("域名【%s】未查询到配置", domain));
        }

        if (appConfigs.size() > 1) {
            throw new ServiceException(String.format("域名【%s】查询到%s条配置", domain, appConfigs.size()));
        }

        wxCpDto.setAppConfigs(appConfigs);

        return wxCpDto;
    }


}
